#include <GL\glut.h>
#include <math.h>
#include "drawing.h"
#include "engine.h"

void DrawRound (Decart place, double radius)
{
	glBegin (GL_POLYGON);
		for (float i = 0; i < 2 * PI; i += PI / 18)
			glVertex2d (place.X () + radius * Zoom * cos (i), 
				place.Y () + radius * Zoom * sin (i));
	glEnd ();
}

void DrawCircle (Decart place, double radius)
{
	glBegin (GL_LINE_LOOP);
		for (float i = 0; i < 2 * PI; i += PI / 18)
			glVertex2d (place.x+ radius * cos (i), place.y + radius * sin (i));
	glEnd ();
}

void DrawBitmapText (char *string, void *font, float x, float y)
{
	char *c;
	glRasterPos3f (x, y, 0);
	for (c = string; *c != '\0'; c++) glutBitmapCharacter (font, *c);
}

void DrawStrokeText (char *string, void *font, int x, int y, int z)
{
	char *c;
	glPushMatrix ();
	glTranslatef (x, y, z);
	glScalef (0.2, 0.2, 1.0);
	for (c = string; *c != '\0'; c++) glutStrokeCharacter (font, *c);
	glPopMatrix ();
}

void SetObjectColor (int N)
{
	switch (Object[N].type)
	{
	case Star:
		glColor3d (0.8, 0.8, 0.2);
	break;
	case Planet:
		glColor3d (0.2, 0.8, 0.2);
	break;
	case Comet:
		glColor3d (0.9, 0.9, 0.9);
	break;
	default: // Meteor
		glColor3d (0.5, 0.5, 0.5);
	break;
	}
}

void DrawObject (int N)
{
	SetObjectColor (N);
	DrawRound (Object[N].place, Object[N].GetSize ());
}

void DrawObjectDirection (int N)
{
	Polar Buffer;
	glColor3d (0.0, 1.0, 0.0);
	glBegin (GL_LINES);
		glVertex2d (Object[N].place.X (), Object[N].place.Y ());
		glVertex2d (Object[N].place.X () + Object[N].speed.x * 10 * Zoom,
			Object[N].place.Y () + Object[N].speed.y * 10 * Zoom);
	glEnd ();
}

void DrawObjectMark (int N)
{
	glColor3d (1.0, 1.0, 1.0);
	DrawCircle ((Object[N].place - Tr) * Zoom, Object[N].GetSize () * Zoom + 3);
}

void DrawObjectTail (int N)
{
	switch (Skin)
	{
	case Contur:
	{
		
	}
	break;
	case Usual:
	{
	glBegin (GL_LINE_LOOP);
		glColor3d (0.7, 0.7, 0.7);
		Polar buf;
		buf.angle = (Object[N].place - Object[N].tail[1]).Angle () - PI / 2;
		buf.radius = (Object[N].GetSize () - 1) * Zoom;
		if (Object[N].speed.Distance () > 10 / CountingAcuracy)
		{
			for (double i = buf.angle; i < buf.angle + PI; i += PI / 9)
			{
				glVertex2d (Object[N].place.X () + buf.radius * cos (i),
					Object[N].place.Y () + buf.radius * sin (i));
			}
			for (int i = 1; i < TailLenth - 1; i++)
			{
				buf.angle = (Object[N].tail[i] - Object[N].tail[i + 1]).Angle () + PI / 2;
				buf.radius = (Object[N].GetSize () - 1) * (TailLenth - i) * Zoom / TailLenth;
				glVertex2d (Object[N].tail[i].X () + buf.radius * cos (buf.angle),
					Object[N].tail[i].Y () + buf.radius * sin (buf.angle));
			}
			glVertex2d (Object[N].tail[TailLenth - 1].X (), Object[N].tail[TailLenth - 1].Y ());
			for (int i = TailLenth - 1; i > 0; i--)
			{
				Polar buf;
				buf.angle = (Object[N].tail[i] - Object[N].tail[i - 1]).Angle () + PI / 2;
				buf.radius = Object[N].GetSize () * (TailLenth - i) * Zoom / TailLenth;
				glVertex2d (Object[N].tail[i].X () + buf.radius * cos (buf.angle),
					Object[N].tail[i].Y () + buf.radius * sin (buf.angle));
			}
		}
		else DrawCircle ((Object[N].place - Tr) * Zoom, Object[N].GetSize() * Zoom + 1);
	glEnd ();
	}
	break;
	}
}

void DrawMiniMap ()
{
	glColor3d(0.0, 0.0, 0.0);
	glBegin(GL_POLYGON);
		glVertex2d(4 * Win.W / 10 - 3, - 4 * Win.H / 10 + 3);
		glVertex2d(Win.W / 2, - 4 * Win.H / 10 + 3);
		glVertex2d(Win.W / 2, - Win.H / 2);
		glVertex2d(4 * Win.W / 10 - 3, - Win.H / 2);
	glEnd();
	
	glColor3d(0.0, 0.4, 0.0);
	glBegin(GL_POLYGON);
		glVertex2d(9 * Win.W / 20 + Tr.x / 20 / SBS - Win.W / Zoom / 40 / SBS,
			- 9 * Win.H / 20 + Tr.y / 20 / SBS - Win.H / Zoom / 40 / SBS);
		glVertex2d(9 * Win.W / 20 + Tr.x / 20 / SBS - Win.W / Zoom / 40 / SBS,
			- 9 * Win.H / 20 + Tr.y / 20 / SBS + Win.H / Zoom / 40 / SBS);
		glVertex2d(9 * Win.W / 20 + Tr.x / 20 / SBS + Win.W / Zoom / 40 / SBS,
			- 9 * Win.H / 20 + Tr.y / 20 / SBS + Win.H / Zoom / 40 / SBS);
		glVertex2d(9 * Win.W / 20 + Tr.x / 20 / SBS + Win.W / Zoom / 40 / SBS,
			- 9 * Win.H / 20 + Tr.y / 20 / SBS - Win.H / Zoom / 40 / SBS);
	glEnd();

	glColor3d(1.0, 1.0, 1.0);
	glBegin(GL_LINE_LOOP);
		glVertex2d(Win.W / 2 - Win.W / 10, - Win.H / 2 + Win.H / 10 + 1);
		glVertex2d(Win.W / 2, - Win.H / 2 + Win.H / 10);
		glVertex2d(Win.W / 2, - Win.H / 2);
		glVertex2d(Win.W / 2 - Win.W / 10, - Win.H / 2);
	glEnd();

	glBegin(GL_POINTS);
	for (int i = 0; i < ObjectAmount; i++)
		if (Object[i].exist)
		{
			SetObjectColor(i);
			glVertex2d(9 * Win.W / 20 + Object[i].place.x / 20 / SBS, - 9 * Win.H / 20 + Object[i].place.y / 20 / SBS);
		};
	glEnd();
}

void DrawToolbar ()
{
	glColor3d (0.0, 0.0, 0.0);
	glBegin (GL_POLYGON);
		glVertex2d (- 243, - Win.H / 2 + 0);
		glVertex2d (- 243, - Win.H / 2 + 32);
		glVertex2d (243, - Win.H / 2 + 32);
		glVertex2d (243, - Win.H / 2 + 0);
	glEnd ();
	
	glColor3d (1.0, 1.0, 1.0);
	glBegin (GL_LINE_LOOP);
		glVertex2d (- 241, - Win.H / 2 );
		glVertex2d (241, - Win.H / 2);
		glVertex2d (241, - Win.H / 2 + 30);
		glVertex2d (- 241, - Win.H / 2 + 30);
	glEnd ();
	glBegin (GL_LINES);
		glVertex2d (- 211, - Win.H / 2);
		glVertex2d (- 211, - Win.H / 2 + 30);

		glVertex2d (211, - Win.H / 2);
		glVertex2d (211, - Win.H / 2 + 30);
		
		glVertex2d (12, - Win.H / 2);
		glVertex2d (12, - Win.H / 2 + 30);
	glEnd ();

	glColor3d (0.6, 0.0, 0.0);
	glBegin (GL_POLYGON);
		glVertex2d (- 251, - Win.H / 2 + 35);
		glVertex2d (- 253, - Win.H / 2 + 35);
		glVertex2d (- 255, - Win.H / 2 + 33);
		glVertex2d (- 255, - Win.H / 2 + 32);
		glVertex2d (- 228, - Win.H / 2 + 4);
		glVertex2d (- 227, - Win.H / 2 + 4);
		glVertex2d (- 225, - Win.H / 2 + 7);
		glVertex2d (- 225, - Win.H / 2 + 9);
	glEnd ();
	glBegin (GL_POLYGON);
		glVertex2d (- 229, - Win.H / 2 + 35);
		glVertex2d (- 227, - Win.H / 2 + 35);
		glVertex2d (- 225, - Win.H / 2 + 33);
		glVertex2d (- 225, - Win.H / 2 + 31);
		glVertex2d (- 251, - Win.H / 2 + 4);
		glVertex2d (- 252, - Win.H / 2 + 4);
		glVertex2d (- 255, - Win.H / 2 + 8);
		glVertex2d (- 255, - Win.H / 2 + 9);
	glEnd ();
	
	glColor3d (0.0, 0.6, 0.0);
	glBegin (GL_POLYGON);
		glVertex2d (233, - Win.H / 2 + 18);
		glVertex2d (230, - Win.H / 2 + 15);
		glVertex2d (240, - Win.H / 2 + 5);
		glVertex2d (241, - Win.H / 2 + 10);
	glEnd ();
	glBegin (GL_POLYGON);
		glVertex2d (240, - Win.H / 2 + 5);
		glVertex2d (254, - Win.H / 2 + 33);
		glVertex2d (250, - Win.H / 2 + 35);
		glVertex2d (237, - Win.H / 2 + 9);
	glEnd ();

	glColor3d (0.0, 0.6, 0.0);
	glBegin (GL_LINE_LOOP);
		glVertex2d (- 150, - Win.H / 2 + 3);
		glVertex2d (- 150, - Win.H / 2 + 27);
		glVertex2d (3, - Win.H / 2 + 27);
		glVertex2d (3, - Win.H / 2 + 3);
	glEnd ();
	glBegin (GL_LINES);
		glVertex2d (- 123, - Win.H / 2 + 3);
		glVertex2d (- 123, - Win.H / 2 + 27);

		glVertex2d (- 25, - Win.H / 2 + 3);
		glVertex2d (- 25, - Win.H / 2 + 27);
	glEnd ();
	glBegin (GL_POLYGON);
		glVertex2d (- 140, - Win.H / 2 + 15);
		glVertex2d (- 133, - Win.H / 2 + 22);
		glVertex2d (- 133, - Win.H / 2 + 8);
	glEnd ();
	glBegin (GL_POLYGON);
		glVertex2d (- 8, - Win.H / 2 + 15);
		glVertex2d (- 15, - Win.H / 2 + 22);
		glVertex2d (- 15, - Win.H / 2 + 8);
	glEnd ();
	
	glColor3d (1.0, 1.0, 1.0);
	DrawBitmapText ("TYPE", GLUT_BITMAP_HELVETICA_18,
		- 205, -Win.H / 2 + 8);
	
	switch (Object[EditObject].type)
	{
		case Star:
			DrawBitmapText ("STAR", GLUT_BITMAP_HELVETICA_18,
				- 100, -Win.H / 2 + 8);
		break;
		case Planet:
			DrawBitmapText ("PLANET", GLUT_BITMAP_HELVETICA_18,
				- 113, -Win.H / 2 + 8);
		break;
		case Meteor:
			DrawBitmapText ("METEOR", GLUT_BITMAP_HELVETICA_18,
				- 115, -Win.H / 2 + 8);
		break;
		case Comet:
			DrawBitmapText ("COMET", GLUT_BITMAP_HELVETICA_18,
				- 108, -Win.H / 2 + 8);
		break;
		default:
		break;
	}

	DrawBitmapText ("WEIHGT", GLUT_BITMAP_HELVETICA_18,
		23, -Win.H / 2 + 8);

	glColor3d (0.0, 0.6, 0.0);
	glBegin (GL_LINE_LOOP);
		glVertex2d (108, - Win.H / 2 + 3);
		glVertex2d (108, - Win.H / 2 + 27);
		glVertex2d (202, - Win.H / 2 + 27);
		glVertex2d (202, - Win.H / 2 + 3);
	glEnd ();
	
	glColor3d (0.0, 1.0, 0.0);
	glBegin (GL_POLYGON);
		glVertex2d (110, - Win.H / 2 + 5);
		glVertex2d (110, - Win.H / 2 + 26);
		glVertex2d (101 + Object[EditObject].weight, - Win.H / 2 + 26);
		glVertex2d (101 + Object[EditObject].weight, - Win.H / 2 + 5);
	glEnd ();
}

void DrawMenu ()
{
	glColor3d (0.3, 0.0, 0.0);
	glBegin (GL_POLYGON);
		glVertex2d (- Win.W / 2, Win.H / 2);
		glVertex2d (- Win.W / 2, Win.H / 2 - 21);
		glVertex2d (Win.W / 2, Win.H / 2 - 21);
		glVertex2d (Win.W / 2, Win.H / 2);
	glEnd ();
}

void DrawSandBox(double Size)
{
	glColor3d(1.0, 1.0, 1.0);
	glBegin(GL_LINE_LOOP);
		glVertex2d ((- Win.W * Size - Tr.x) * Zoom, (- Win.H * Size - Tr.y) * Zoom);
		glVertex2d ((Win.W * Size - Tr.x) * Zoom, (- Win.H * Size - Tr.y) * Zoom);
		glVertex2d ((Win.W * Size - Tr.x) * Zoom, (Win.H * Size - Tr.y) * Zoom);
		glVertex2d ((- Win.W * Size - Tr.x) * Zoom, (Win.H * Size - Tr.y) * Zoom);
	glEnd ();
}

void ShowAlert ()
{
	glColor3d (1.0, 0.0, 0.0);
	switch (Alert)
	{
	case MaxObjectAmount:
		DrawBitmapText ("You already have max object amount", GLUT_BITMAP_TIMES_ROMAN_24,
		 - 160, - Win.H / 2 + 65);
	break;
	case TooCloseToOther:
		DrawBitmapText ("Too close to other object", GLUT_BITMAP_TIMES_ROMAN_24,
		 - 100, - Win.H / 2 + 65);
	break;
	case ImpossibleLocation:
		DrawBitmapText ("Impossible to place here", GLUT_BITMAP_TIMES_ROMAN_24,
		 - 98, - Win.H / 2 + 65);
	break;
	default:
	break;
	}
}

void DrawResistanceRegulator ()
{

}

void ShowHelp ()
{

}